﻿using System;
using System.Text;

namespace Html
{
    class Parser
    {
        private Scanner scanner;

        public Parser(string value)
        {
            scanner = new Scanner(value);

            Token token;
            while ((token = scanner.Read()) != null)
            {
                if (token.Kind == Kind.Whitespace)
                {
                    Console.WriteLine("Whitespace [ ]");
                }
                else
                {
                    if (token.Kind == Kind.LessThan)
                    {
                        Token peek;
                        if ((peek = scanner.Peek()) != null)
                        {
                            if (peek.Kind == Kind.Text)
                            {
                                ParseStartTag();
                                continue;
                            }
                            if (peek.Kind == Kind.Slash)
                            {
                                ParseEndTag();
                                continue;
                            }
                            if (peek.Kind == Kind.ExclamationMark)
                            {
                                ParseDeclaration();
                                continue;
                            }
                        }
                    }

                    Console.WriteLine("Text [...]");
                }
            }
        }

        private void ParseStartTag()
        {
            Token token;
            if ((token = scanner.Read()) != null && token.Kind == Kind.Text)
            {
                string name = token.Value;
                Console.WriteLine("StartTag [{0}]", name);

                ParseAttributes();
            }
        }

        private void ParseAttributes()
        {
            Token token;
            while ((token = scanner.Read()) != null)
            {
                if (token.Kind == Kind.GreaterThan)
                {
                    break;
                }
                if (token.Kind == Kind.Text)
                {
                    string name = token.Value;
                    Console.WriteLine("Attribute Name [{0}]", name);

                    if ((token = scanner.Peek()) != null && token.Kind == Kind.Whitespace)
                    {
                        token = scanner.Read();
                    }
                    if ((token = scanner.Peek()) != null && token.Kind == Kind.Equals)
                    {
                        ParseAttributeValue();
                    }
                }
            }
        }

        private void ParseEndTag()
        {
            Token token;
            if ((token = scanner.Read()) != null && token.Kind == Kind.Slash)
            {
                if ((token = scanner.Peek()) != null && token.Kind == Kind.Text)
                {
                    string name = token.Value;
                    Console.WriteLine("EndTag [{0}]", name);
                }
                while ((token = scanner.Read()) != null)
                {
                    if (token.Kind == Kind.GreaterThan)
                    {
                        break;
                    }
                }
            }
        }

        private void ParseDeclaration()
        {
            Token token;
            if ((token = scanner.Read()) != null && token.Kind == Kind.ExclamationMark)
            {
                while ((token = scanner.Read()) != null)
                {
                    if (token.Kind == Kind.GreaterThan)
                    {
                        break;
                    }
                }
            }
        }

        private void ParseAttributeValue()
        {
            Token token;
            if ((token = scanner.Read()) != null && token.Kind == Kind.Equals)
            {
                if ((token = scanner.Peek()) != null && token.Kind == Kind.Whitespace)
                {
                    token = scanner.Read();
                }
                if ((token = scanner.Peek()) != null)
                {
                    if (token.Kind == Kind.QuotationMarks | token.Kind == Kind.Apostrophe)
                    {
                        token = scanner.Read();
                        Kind kind = token.Kind;
                        StringBuilder builder = new StringBuilder();
                        while ((token = scanner.Read()) != null)
                        {
                            if (token.Kind == kind)
                            {
                                break;
                            }
                            else
                            {
                                builder.Append(token.Value);
                            }
                        }
                        string value = builder.ToString();
                        Console.WriteLine("Attribute Value [{0}]", value);
                    }
                    else
                    {
                        if (token.Kind == Kind.Text)
                        {
                            token = scanner.Read();
                            string value = token.Value;
                            Console.WriteLine("Attribute Value [{0}]", value);
                        }
                    }
                }
            }
        }
    }
}
